import pyaudio
import wave
import numpy as np
import matplotlib.pyplot as plt
import random
import tkinter as tk

# 音频输入参数
format = pyaudio.paInt16
channels = 1
rate = 44100
chunk_size = 1024
record_seconds = 2
cooldown_time = 1  # HIT 计数的冷却时间，单位为秒

# 创建一个PyAudio对象
audio = pyaudio.PyAudio()

# 打开音频输入流
stream = audio.open(format=format,
                    channels=channels,
                    rate=rate,
                    input=True,
                    frames_per_buffer=chunk_size)

# 上一次HIT的时间
last_hit_time = None

def calculate_threshold(audio_data):
    max_amplitude = np.max(audio_data)
    hit_threshold = int(0.5 * max_amplitude)
    return hit_threshold

def count_hits(audio_data, threshold):
    hit_count = 0
    skip_count = 0

    for i, sample in enumerate(audio_data):
        if skip_count > 0:
            skip_count -= 1
            continue

        if sample > threshold:
            hit_count += 1
            skip_count = int(rate / chunk_size * cooldown_time)

    return hit_count

def save_audio(filename, frames):
    with wave.open(filename, "wb") as wf:
        wf.setnchannels(channels)
        wf.setsampwidth(audio.get_sample_size(format))
        wf.setframerate(rate)
        wf.writeframes(b''.join(frames))

def plot_waveform(audio_data):
    # 创建时间轴
    time_axis = np.arange(0, len(audio_data)) / rate

    # 绘制波形图
    plt.figure()
    plt.plot(time_axis, audio_data)
    plt.xlabel("Time (s)")
    plt.ylabel("Amplitude")
    plt.title("Waveform")
    plt.show()

def get_user_choice():
    user_choice = user_choice_var.get()
    root.destroy()

def get_computer_choice():
    choices = ['剪刀', '石头', '布']
    return random.choice(choices)

def determine_winner(user_choice, computer_choice):
    if user_choice == computer_choice:
        return "平局"
    elif (user_choice == '剪刀' and computer_choice == '布') \
            or (user_choice == '石头' and computer_choice == '剪刀') \
            or (user_choice == '布' and computer_choice == '石头'):
        return "用户胜利"
    else:
        return "电脑胜利"

def update_gui():
    global frames, audio_data, hit_threshold, hit_count

    root = tk.Tk()
    root.title("剪刀石头布游戏")
    root.geometry("500x300")

    canvas = tk.Canvas(root, width=500, height=200)
    canvas.pack()

    if frames:
        plot_waveform(audio_data)
        frames = []
        audio_data = []

    threshold_label = tk.Label(root, text="阈值:")
    threshold_label.place(x=20, y=220)

    threshold_value = tk.Label(root, text=str(hit_threshold))
    threshold_value.place(x=70, y=220)

    hit_count_label = tk.Label(root, text="HIT次数:")
    hit_count_label.place(x=20, y=250)

    hit_count_value = tk.Label(root, text=str(hit_count))
    hit_count_value.place(x=100, y=250)

    choice_label = tk.Label(root, text="请选择(剪刀/石头/布):")
    choice_label.place(x=200, y=220)

    user_choice_var.set("")
    choice_entry = tk.Entry(root, textvariable=user_choice_var)
    choice_entry.place(x=350, y=220)

    submit_button = tk.Button(root, text="提交", command=get_user_choice)
    submit_button.place(x=400, y=250)

    root.mainloop()

def play_game():
    hit_count = 0
    player_win_count = 0
    computer_win_count = 0

    while True:
        print("欢迎来到剪刀石头布游戏！")

        input("按空格键开始录制音频...")

        print("录音开始...")
        frames = []
        for i in range(int(rate / chunk_size * record_seconds)):
            data = stream.read(chunk_size)
            frames.append(data)

        current_time = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
        filename = f"audio_{current_time}.wav"
        save_audio(filename, frames)
        print(f"音频已保存为：{filename}")

        with wave.open(filename, "rb") as wf:
            num_frames = wf.getnframes()
            audio_data = np.frombuffer(wf.readframes(num_frames), dtype=np.int16)

        hit_threshold = calculate_threshold(audio_data)
        hit_count = count_hits(audio_data, hit_threshold)
        print(f"HIT次数：{hit_count}")

        if hit_count == 1:
            user_choice = '剪刀'
        elif hit_count == 2:
            user_choice = '石头'
        elif hit_count == 3:
            user_choice = '布'
        else:
            update_gui()
            user_choice = user_choice_var.get()

        computer_choice = get_computer_choice()
        print("用户选择:", user_choice)
        print("电脑选择:", computer_choice)
        winner = determine_winner(user_choice, computer_choice)
        print("结果:", winner)

        if winner == "用户胜利":
            player_win_count += 1
        elif winner == "电脑胜利":
            computer_win_count += 1

        print("玩家:", player_win_count, "电脑:", computer_win_count)

        user_input = input("按回车键继续录制音频，输入其他字符退出程序：")
        if user_input != "":
            break

        print("录音开始...")

    print("录音结束...")

play_game()
